package com.gtmc.gclub.common;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gtmc.gclub.wx.dto.AccessToken;
import com.gtmc.gclub.wx.dto.DepUser;
import com.gtmc.gclub.wx.dto.Department;
import com.gtmc.gclub.wx.dto.DepartmentList;
import com.gtmc.gclub.wx.dto.JsApiTicket;
import com.gtmc.gclub.wx.dto.QyUserInfo;
import com.gtmc.gclub.wx.dto.TagList;
import com.gtmc.gclub.wx.dto.TagUser;
import com.gtmc.gclub.wx.dto.WxMsgSend;
import com.gtmc.gclub.wx.dto.WxUserInfo;
import com.gtmc.gclub.chat.vo.WxMaterialFileVo;

public class WxUtil {
	private static Logger logger = LoggerFactory.getLogger(WxUtil.class);

	public static AccessToken getWxToken(String id, String secret) {
		System.out.println("info");
		String url = WxApiUrl.WX_ACCESS_TOKEN.replaceAll("ID", id).replaceAll("SECRECT", secret);
		String result = FrameHttpUtil.sendGet(url, "");
		AccessToken token = null;
		if (!"".equals(result)) {
			try {
				token = JSON.parseObject(result, AccessToken.class);
			} catch (Exception e) {
				logger.error("AccessToken:" + "解析json报错" + e.getMessage());
			}
		}
		return token;
	}

	public static QyUserInfo getUserInfo(String token, String code) {
		logger.info("获取微信登录用户信息");
		String url = WxApiUrl.WX_GETUSERINFO.replaceAll("ACCESS_TOKEN", token).replaceAll("CODE", code);
		String result = FrameHttpUtil.sendGet(url, "");
		QyUserInfo userInfo = null;
		if (!"".equals(result)) {
			try {
				userInfo = JSON.parseObject(result, QyUserInfo.class);
			} catch (Exception e) {
				logger.error("QyUserInfo:" + "解析json报错" + e.getMessage());
			}
		}
		return userInfo;
	}

	public static WxUserInfo getWxUserInfo(String token, String userId) {
		logger.info("获取用户详细信息");
		String url = WxApiUrl.WX_USER_GET.replaceAll("ACCESS_TOKEN", token).replaceAll("USERID", userId);
		String result = FrameHttpUtil.sendGet(url, "");
		WxUserInfo userInfo = null;
		if (!"".equals(result)) {
			try {
				userInfo = JSON.parseObject(result, WxUserInfo.class);
			} catch (Exception e) {
				logger.error("WxUserInfo:" + "解析json报错" + e.getMessage());
			}
		}
		return userInfo;
	}

	/**
	 * 获取dealerCode
	 * 
	 * @return
	 */
	public static String getDealerCode(String token, Integer id) {
		logger.info("WX:getDealerCode");
		String url = WxApiUrl.WX_DEPARTMENT_LIST.replaceAll("ACCESS_TOKEN", token).replaceAll("ID", String.valueOf(id));
		String result = FrameHttpUtil.sendGet(url, "");
		DepartmentList dep = null;
		if (!"".equals(result)) {
			try {
				dep = JSON.parseObject(result, DepartmentList.class);
			} catch (Exception e) {
				logger.error("DepartmentList:" + "解析json报错" + e.getMessage());
			}
		}
		String name = "";
		if (dep.getErrcode() == 0) {
			if (dep.getDepartment().size() > 0) {
				boolean flag = false;
				for (Department ment : dep.getDepartment()) {
					if (ment.getId().intValue() == id.intValue()) {
						name = ment.getName();
						flag = true;
					}
					if (flag)
						break;
				}
			}
		}
		return name;
	}

	/**
	 * 获取服务类别
	 * 
	 * @return
	 */
	public static boolean getServerType(String token, String userId, Integer beforeId) {
		logger.info("获取服务类别:getServerType");
		String url = WxApiUrl.WX_TAG_LIST.replaceAll("ACCESS_TOKEN", token).replaceAll("TAGID",
				String.valueOf(beforeId));
		String result = FrameHttpUtil.sendGet(url, "");
		TagList tag = null;
		if (!"".equals(result)) {
			try {
				tag = JSON.parseObject(result, TagList.class);
			} catch (Exception e) {
				logger.error("TagList:" + "解析json报错" + e.getMessage());
			}
		}
		boolean flag = false;
		if (tag.getErrcode() == 0) {
			if (tag.getUserlist().size() > 0) {
				for (TagUser user : tag.getUserlist()) {
					if (userId.equals(user.getUserid())) {
						flag = true;
						break;
					}

				}
			}
		}
		return flag;
	}

	public static JsApiTicket getJsApiTicket(String token) {
		logger.info("获取js调用凭证:getJsApiTicket");
		String url = WxApiUrl.WX_JS_TICKET.replaceAll("ACCESS_TOKE", token);
		String result = FrameHttpUtil.sendGet(url, "");
		JsApiTicket ticket = null;
		if (!"".equals(result)) {
			try {
				ticket = JSON.parseObject(result, JsApiTicket.class);
			} catch (Exception e) {
				logger.error("JsApiTicket:" + "解析json报错" + e.getMessage());
			}
		}
		return ticket;
	}

	/**
	 * houkaihua update 
	 * @author qianjs163@163.com
	 * @return
	 */
	public static WxMaterialFileVo getImage(String token, String serId,WxMediaFileSourceType meterialType) throws Exception{
		logger.info("获取wx图片流:getImage");
		String url = getDownloadFileUrl(token,serId,meterialType);
		Map<String,String> param = new HashMap<String,String>();
		param.put("media_id", serId);
		byte[] data = FrameHttpUtil.getMediaByPost(url,param);
		if(data.length<1024) {
			logger.debug("getImage图片流可能获取失败："+new String(data));
		}
		WxMaterialFileVo urlEntity = new WxMaterialFileVo();
		urlEntity.setDownloadUrl(url);
		urlEntity.setData(data);
		return urlEntity;
	}
	/**
	 * @author houkaihua 
	 * @return
	 */
	public static WxMaterialFileVo getVoice(String token, String serId,WxMediaFileSourceType meterialType) throws Exception{
		logger.info("获取wx音频流:getVoice");
		String url = getDownloadFileUrl(token,serId,meterialType);
		Map<String,String> param = new HashMap<String,String>();
		param.put("media_id", serId);
		byte[] data = FrameHttpUtil.getMediaByPost(url,param);
		if(data.length<1024) {
			logger.debug("getVoice音频流可能获取失败："+new String(data));
		}
		WxMaterialFileVo urlEntity = new WxMaterialFileVo();
		urlEntity.setDownloadUrl(url);
		urlEntity.setData(data);
		return urlEntity;
	}
	
	/**
	 * 获取视频流（测试阶段）
	 * @param token
	 * @param serId
	 * @return
	 */
	public static WxMaterialFileVo getVideo(String token, String serId,WxMediaFileSourceType meterialType) throws Exception{
		logger.info("获取wx视频流:getVideo");
		String url = getDownloadFileUrl(token,serId,meterialType);
//		return FrameHttpUtil.getMedia(url);
		Map<String,String> param = new HashMap<String,String>();
		param.put("media_id", serId);
		byte[] postData = FrameHttpUtil.getMediaByPost(url,param);
		String postRes = new String(postData);
		JSONObject json = JSON.parseObject(postRes);
		String fileDownUrl = (String) json.get("down_url");
		String title = (String) json.get("title");
		String description = (String) json.get("description");
		logger.debug("获取下载地址:"+fileDownUrl);
		byte[] mediaData = FrameHttpUtil.getMedia(fileDownUrl);
		WxMaterialFileVo fileEntity = new WxMaterialFileVo();
		fileEntity.setTitle(title);
		fileEntity.setDescription(description);
		fileEntity.setDownloadUrl(fileDownUrl);
		fileEntity.setData(mediaData);
		return fileEntity;
	}
	public static String getDownloadFileUrl(String token, String serId,WxMediaFileSourceType meterialType) {
		logger.debug("获取URL ： getDownloadFileUrl");
		String baseUrl = "" ;
		switch (meterialType) {
		case temp:
			baseUrl = WxApiUrl.WX_MEDIA;
			break;
		case permanent :
			baseUrl = WxApiUrl.WX_GET_PERMANENT_ONE;
//			baseUrl = "https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=ACCESS_TOKEN";
			break;
		default:
			break;
		}
		logger.debug("正确的URL应该是https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=ACCESS_TOKEN");
		logger.debug("打印WxApiUrl.WX_GET_PERMANENT_ONE"+WxApiUrl.WX_GET_PERMANENT_ONE);
		logger.debug("打印baseUrl"+baseUrl);
		String url = baseUrl.replaceAll("ACCESS_TOKEN", token).replaceAll("MEDIA_ID", serId);
		logger.info("获取wx媒体文件流:getDownloadFileUrl:"+url);
		return url;
	}
	public static void main(String[] args) throws IOException {
//		String mediaId = "jitregIbB_sSct7z2JW0oLe4yBF0F8WzsOZuzx-6i_Q";
//		String mediaId = "jitregIbB_sSct7z2JW0oPv4r_Rvv4CFjbXib5ABiBk";
//		String mediaId = "jitregIbB_sSct7z2JW0oGaxNdQ7tujen3J2RTy3bDQ";
//		String mediaId = "jitregIbB_sSct7z2JW0oISWusWhTC8JQVNaZD80jrs";
//		String mediaId = "jitregIbB_sSct7z2JW0oOuvzfY_ytdotnKOHCGlvF8";
		String mediaId = "jitregIbB_sSct7z2JW0oISWusWhTC8JQVNaZD80jrs";// 图片
		String token = "6_Gb64oH_o0i5XaQ0FgdrxjOppphoZOJ7aw6KfOnkycz7twofI2uwwdZ3-5qTu5Jc8h3SuZaGU_P4lACnluCtdTtAH1IWE7u1xOc-wW4OlWL293sJr7eNu9h7KRpcXEXcAIAFMF" ;
//		String tempUrl = WxApiUrl.WX_MEDIA ;
//		String tempUrl = WxApiUrl.WX_GET_PERMANENT_SOURCE ;
		try {
			List<String> allMaterial = WxUtil.getAllMaterial(token, WxMaterialTypeEnum.video);
			logger.debug("读取完毕："+allMaterial);
		} catch (Exception e) {
			e.printStackTrace();
		}
//		String tempUrl = "https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=ACCESS_TOKEN" ;
//		tempUrl = tempUrl.replaceAll("ACCESS_TOKEN", token).replaceAll("MEDIA_ID", mediaId);
//		logger.debug("首先用临时素材url:"+tempUrl);
////		byte[] mediaGet = FrameHttpUtil.getMedia(tempUrl);
////		logger.debug("get方式获取："+new String(mediaGet));
//		Map<String,String> param = new HashMap<String,String>();
//		param.put("media_id", mediaId);
//		byte[] mediaByPost = FrameHttpUtil.getMediaByPost(tempUrl,param);
////		byte[] mediaByPost = null ;
////		try {
////			mediaByPost = FrameHttpUtil.getMediaByPost(tempUrl);
////		} catch (Exception e) {
////			logger.debug("获取微信视频流失败");
////			e.printStackTrace();
////		}
//		logger.debug("看一下文件数据byte:"+mediaByPost.length);
////		logger.debug("post方式获取："+new String(mediaByPost));
//		File file = new File("D:\\filestore\\test.mp3");
//		ByteArrayInputStream in = new ByteArrayInputStream(mediaByPost);
//		BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
//		int len = 0;
//		byte[] temp = new byte[1024];
//		while((len = in.read(temp))>0) {
//			out.write(temp);
//		}
//		out.close();
//		out = null ;
//		in.close();
//		in = null ;
//		logger.debug("写文件完毕");
	}

	public static WxMsgSend sendWxMsg(String token, String userId, int agentId, String content) {
		logger.info("推送微信消息:sendWxMsg");

		String url = WxApiUrl.WX_SEND_MSG.replaceAll("ACCESS_TOKE", token);

		String contMsg = "{\"touser\": \"%s\",   \"msgtype\": \"text\",\"agentid\": \"%s\","
				+ "\"text\":{\"content\": \"%s\"}}";
		contMsg = String.format(contMsg, userId, String.valueOf(agentId), content);
		logger.info(contMsg);
		String result = FrameHttpUtil.post(url, contMsg);
		logger.info(result);
		WxMsgSend msg = null;
		if (!"".equals(result)) {
			try {
				msg = JSON.parseObject(result, WxMsgSend.class);
			} catch (Exception e) {
				logger.error("WxMsgSend:" + "解析json报错" + e.getMessage());
			}
		}

		return msg;
	}

	/**
	 * 获取部门列表
	 * 
	 * @author qianjs163@163.com
	 * @param token
	 * @param id
	 * @return
	 */
	public static DepartmentList getDepartmentList(String token, Integer id) {
		logger.info("wx:getDepartmentList");
		String url = WxApiUrl.WX_DEPARTMENT_LIST.replaceAll("ACCESS_TOKEN", token).replaceAll("ID", String.valueOf(id));
		String result = FrameHttpUtil.sendGet(url, "");
		DepartmentList dep = null;
		if (!"".equals(result)) {
			try {
				dep = JSON.parseObject(result, DepartmentList.class);
			} catch (Exception e) {
				logger.error("DepartmentList:" + "解析json报错" + e.getMessage());
			}
		}
		return dep;
	}

	/**
	 * 获取标签成员
	 * 
	 * @author qianjs163@163.com
	 * @param token
	 * @param id
	 * @return
	 */
	public static TagList getTagList(String token, Integer id) {
		logger.info("wx:getTagList");
		String url = WxApiUrl.WX_TAG_LIST.replaceAll("ACCESS_TOKEN", token).replaceAll("TAGID", String.valueOf(id));
		String result = FrameHttpUtil.sendGet(url, "");
		TagList tag = null;
		if (!"".equals(result)) {
			try {
				tag = JSON.parseObject(result, TagList.class);
			} catch (Exception e) {
				logger.error("TagList:" + "解析json报错" + e.getMessage());
			}
		}
		return tag;
	}

	public static DepUser getDepUser(String token, Integer id, String fetch_child, String status) {
		logger.info("wx:getDepUser");
		String url = WxApiUrl.WX_SIMPLELIST.replaceAll("ACCESS_TOKEN", token)
				.replaceAll("DEPARTMENT_ID", String.valueOf(id)).replaceAll("FETCH_CHILD", fetch_child)
				.replaceAll("STATUS", status);
		String result = FrameHttpUtil.sendGetToBig(url, "");
		DepUser tag = null;
		if (!"".equals(result)) {
			try {
				tag = JSON.parseObject(result, DepUser.class);
			} catch (Exception e) {
				logger.error("TagList:" + "解析json报错" + e.getMessage());
			}
		}
		return tag;
	}
	
	public static String uploadVideo(String url, String filePath, String title, String introduction) {  
        String result = null;    
          
        HttpURLConnection downloadCon = null;  
        InputStream inputStream = null;  
        try {  
            URL urlFile = new URL(filePath);  
            downloadCon = (HttpURLConnection) urlFile.openConnection();  
            inputStream = downloadCon.getInputStream();  
                  
            URL urlObj = new URL(url);   
            HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();  
            conn.setConnectTimeout(5000);  
            conn.setReadTimeout(30000);    
            conn.setDoOutput(true);    
            conn.setDoInput(true);    
            conn.setUseCaches(false);    
            conn.setRequestMethod("POST");   
            conn.setRequestProperty("Connection", "Keep-Alive");  
            conn.setRequestProperty("Cache-Control", "no-cache");  
            String boundary = "-----------------------------"+System.currentTimeMillis();  
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);  
                          
            OutputStream output = conn.getOutputStream();  
            output.write(("--" + boundary + "\r\n").getBytes());  
            String regex = ".*/([^\\.]+)";  
            output.write(String.format("Content-Disposition: form-data; name=\"media\"; filename=\"%s\"\r\n", filePath.replaceAll(regex, "$1")).getBytes());    
            output.write("Content-Type: video/mp4 \r\n\r\n".getBytes());  
            int bytes = 0;  
            byte[] bufferOut = new byte[1024];  
            while ((bytes = inputStream.read(bufferOut)) != -1) {  
                output.write(bufferOut, 0, bytes);  
            }  
            inputStream.close();  
              
            output.write(("--" + boundary + "\r\n").getBytes());  
            output.write("Content-Disposition: form-data; name=\"description\";\r\n\r\n".getBytes());  
            output.write(String.format("{\"title\":\"%s\", \"introduction\":\"%s\"}",title,introduction).getBytes());  
            output.write(("\r\n--" + boundary + "--\r\n\r\n").getBytes());  
            output.flush();  
            output.close();  
            inputStream.close();  
            InputStream resp = conn.getInputStream();  
            StringBuffer sb = new StringBuffer();  
            while((bytes= resp.read(bufferOut))>-1)  
            sb.append(new String(bufferOut,0,bytes,"utf-8"));  
            resp.close();  
            result = sb.toString();  
        } catch (IOException e) {  
            e.printStackTrace();    
            return null;    
        }  
        return result;  
    }  
	
	/**
	 * 获取永久素材
	 */
	public static List<String> getAllMaterial(String token,WxMaterialTypeEnum type) throws Exception{
		// 微信永久素材不保存文本和mpnews
		if(type==WxMaterialTypeEnum.text || type==WxMaterialTypeEnum.mpnews) {
			return new ArrayList<String>();
		}
		Integer pageSize = 20;
		String url = WxApiUrl.WX_GET_PERMANENT_SOURCE.replaceAll("ACCESS_TOKEN", token);
		String contMsg = "{\"type\":\"%s\",\"offset\":\"%s\",\"count\":\"%s\"}";
		contMsg = String.format(contMsg,type.name(), 0, pageSize);
		logger.info("获取第1页视频素材开始："+url+"\n["+contMsg+"]");
		String result = FrameHttpUtil.post(url, contMsg);
		logger.info("获取第1页视频素材结果是否成功:"+(!result.isEmpty()));
		JSONObject jsonMap = JSON.parseObject(result);
		List<String> resultList = new ArrayList<String>();
		resultList.add(result);
		Integer total_count = jsonMap.getInteger("total_count");
		Integer item_count = jsonMap.getInteger("item_count");
		logger.debug(type.name()+"素材一共"+total_count+"个，本次拉取"+item_count+"个");
		if(total_count==null || item_count==null) {
			return new ArrayList<String>();
		}
		Integer total_page = total_count/pageSize + (total_count%pageSize ==0 ? 0 :1);
		logger.debug("一共"+total_count+"条，每页"+pageSize+"条,总页数为"+total_page);
		if(total_count > pageSize) {
			for(int i = 1; i < total_page ; i++) {
				contMsg = "{\"type\":\"%s\",\"offset\":\"%s\",\"count\":\"%s\"}";
				contMsg = String.format(contMsg,type.name(), i*pageSize, (i==(total_page-1) ? total_count%pageSize : pageSize));
				logger.info("获取第"+(i+1)+"页视频素材开始："+contMsg);
				String tempResult = FrameHttpUtil.post(url, contMsg);
				logger.info("获取第"+(i+1)+"页视频素材结果是否为空："+tempResult.length());
				resultList.add(tempResult);
			}
		}
		logger.debug("获取的"+type.name()+"素材信息："+resultList.size());
		return resultList;
	}
	
	private static void writeFile(byte[] fileDate,File file) throws Exception{
		InputStream in = new ByteArrayInputStream(fileDate);
		OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
		byte[] temp = new byte[1024];
		int len = 0 ;
		while((len=in.read(temp))>0) {
			out.write(temp, 0, len);
		}
		out.close();
		out = null ;
		in.close();
		in = null ;
		System.out.println("图片读写完毕");
	}
	
	/**
     * @desc ：微信上传素材的请求方法
     *  
     * @param requestUrl  微信上传临时素材的接口url
     * @param file    要上传的文件
     * @return String  上传成功后，微信服务器返回的消息		
	 * @throws IOException 
     */
	public static String uploadTempSourceFile(String token,WxMaterialTypeEnum type,File file) throws IOException {
		String requestUrl = WxApiUrl.WX_ADD_TEMP_SOURCE.replaceAll("ACCESS_TOKEN", token)
				.replaceAll("TYPE", type.name());
		logger.debug("上传临时素材开始，url:"+requestUrl);
	        StringBuffer buffer = new StringBuffer();  
	            //1.建立连接
	            URL url = new URL(requestUrl);
	            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  //打开链接
	            
	            //1.1输入输出设置
	            httpUrlConn.setDoInput(true);
	            httpUrlConn.setDoOutput(true);
	            httpUrlConn.setUseCaches(false); // post方式不能使用缓存
	            //1.2设置请求头信息
	            httpUrlConn.setRequestProperty("Connection", "Keep-Alive");
	            httpUrlConn.setRequestProperty("Charset", "UTF-8");
	            //1.3设置边界
	            String BOUNDARY = "----------" + System.currentTimeMillis();
	            httpUrlConn.setRequestProperty("Content-Type","multipart/form-data; boundary="+ BOUNDARY);

	            // 请求正文信息
	            // 第一部分：
	            //2.将文件头输出到微信服务器
	            StringBuilder sb = new StringBuilder();
	            sb.append("--"); // 必须多两道线
	            sb.append(BOUNDARY);
	            sb.append("\r\n");
	            sb.append("Content-Disposition: form-data;name=\"media\";filelength=\"" + file.length()
	                    + "\";filename=\""+ file.getName() + "\"\r\n");
	            sb.append("Content-Type:application/octet-stream\r\n\r\n");
	            byte[] head = sb.toString().getBytes("utf-8");
	            // 获得输出流
	            OutputStream outputStream = new DataOutputStream(httpUrlConn.getOutputStream());
	            // 将表头写入输出流中：输出表头
	            outputStream.write(head);

	            //3.将文件正文部分输出到微信服务器
	            // 把文件以流文件的方式 写入到微信服务器中
	            DataInputStream in = new DataInputStream(new FileInputStream(file));
	            int bytes = 0;
	            byte[] bufferOut = new byte[1024];
	            while ((bytes = in.read(bufferOut)) != -1) {
	                outputStream.write(bufferOut, 0, bytes);
	            }
	            in.close();
	            //4.将结尾部分输出到微信服务器
	            byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
	            outputStream.write(foot);
	            outputStream.flush();
	            outputStream.close();
	            
	            //5.将微信服务器返回的输入流转换成字符串  
	            InputStream inputStream = httpUrlConn.getInputStream();
	            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
	            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
	            
	            String str = null;  
	            while ((str = bufferedReader.readLine()) != null) {  
	                buffer.append(str);  
	            }  
	            
	            bufferedReader.close();  
	            inputStreamReader.close();  
	            // 释放资源  
	            inputStream.close();  
	            inputStream = null;  
	            httpUrlConn.disconnect();  
	        logger.debug("上传临时素材结束，res:"+buffer);
	        // 格式：{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
	        return buffer.toString();
	}
}
